package cn.jetpiece.cloud.dict.app.modular.dict.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.jetpiece.cloud.core.context.LoginUserContext;
import cn.jetpiece.cloud.core.page.PageFactory;
import cn.jetpiece.cloud.core.query.QueryGenerator;
import cn.jetpiece.cloud.core.util.HttpContext;
import cn.jetpiece.cloud.dict.api.CategoryApi;
import cn.jetpiece.cloud.dict.api.model.params.CreateCategoryParam;
import cn.jetpiece.cloud.dict.api.model.params.UpdateCategoryParam;
import cn.jetpiece.cloud.dict.api.model.query.CategoryQuery;
import cn.jetpiece.cloud.dict.api.model.result.CategoryResult;
import cn.jetpiece.cloud.dict.app.modular.dict.entity.Category;
import cn.jetpiece.cloud.dict.app.modular.dict.service.ICategoryService;
import cn.jetpiece.cloud.dict.app.modular.dict.wrapper.CategoryWrapper;
import cn.jetpiece.cloud.model.model.DictModel;
import cn.jetpiece.cloud.model.model.TreeSelectModel;
import cn.jetpiece.cloud.model.model.TreeSelectResult;
import cn.jetpiece.cloud.model.page.PageResult;
import cn.jetpiece.cloud.model.response.Result;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author hancp
 * @version 1.0
 * @description: 分类字典
 * @date 2021/12/6 11:20
 */
@RestController
@Slf4j
public class CategoryController implements CategoryApi {
    @Autowired
    private ICategoryService categoryService;
//    @Autowired
//    private ICategoryRuleService categoryRuleService;
//    @Autowired
//    private IFillRuleService fillRuleService;


    /**
     * 分页列表查询
     *
     * @param query
     * @return
     */
    @Override
    public Result<PageResult<CategoryResult>> queryPageList(CategoryQuery query) {
        if (StrUtil.isEmpty(query.getPid())) {
            query.setPid("0");
        }
        Category sysCategory = BeanUtil.toBean(query, Category.class);
        //QueryWrapper<SysCategory> queryWrapper = QueryGenerator.initQueryWrapper(sysCategory, HttpContext.getRequestParameters());
        QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("pid", sysCategory.getPid());
        queryWrapper.orderByAsc("sort");
        IPage<Category> pageList = categoryService.page(PageFactory.defaultPage(), queryWrapper);
        PageResult<CategoryResult> pageResult = new CategoryWrapper(pageList).setWrapper(query.getWrapper()).wrapPageResult();
        List<CategoryResult> rows = pageResult.getRows();
//        setResultFillRuleIds(rows);
        return Result.OK(pageResult);
    }

    @Override
    public Result<List<CategoryResult>> listChildren(String pid, CategoryQuery query) {
        query.setPid(pid);
        Result<List<CategoryResult>> result = new Result<>();
        QueryWrapper<Category> queryWrapper = QueryGenerator.initQueryWrapper(BeanUtil.toBean(query, Category.class), HttpContext.getRequestParameters());
        List<Category> list = categoryService.list(queryWrapper);
        List<CategoryResult> resultList = BeanUtil.copyToList(list, CategoryResult.class);
//        setResultFillRuleIds(resultList);
        result.setSuccess(true);
        result.setResult(resultList);
        return result;
    }


    /**
     * 添加
     *
     * @param param
     * @return
     */
    @Override
    public Result<CategoryResult> add(@RequestBody CreateCategoryParam param) {
        Result<CategoryResult> result = new Result<>();
        try {
            Result<String> checkDuplicate = categoryService.checkDuplicate(BeanUtil.toBean(param, UpdateCategoryParam.class));
            if (checkDuplicate.isSuccess()) {
                categoryService.addSysCategory(param);
                result.success("添加成功！");
            } else {
                result.error500(checkDuplicate.getMessage());
            }

        } catch (Exception e) {
            log.error(e.getMessage(), e);
            result.error500("操作失败");
        }
        return result;
    }

    /**
     * 编辑
     *
     * @param param
     * @return
     */
    @Override
    public Result<CategoryResult> edit(@RequestBody UpdateCategoryParam param) {
        Result<CategoryResult> result = new Result<>();
        Category sysCategoryEntity = categoryService.getById(param.getId());
        if (sysCategoryEntity == null) {
            result.error500("未找到对应实体");
        } else {
            Result<String> checkDuplicate = categoryService.checkDuplicate(param);
            if (checkDuplicate.isSuccess()) {
                categoryService.updateSysCategory(param);
                result.success("修改成功!");
            } else {
                result.error500(checkDuplicate.getMessage());
            }
        }
        return result;
    }

    /**
     * 通过id删除
     *
     * @param id
     * @return
     */
    @Override
    public Result<CategoryResult> delete(String id) {
        Result<CategoryResult> result = new Result<>();
        Category category = categoryService.getById(id);
        if (category == null) {
            result.error500("未找到对应实体");
        } else {
            categoryService.deleteSysCategory(id);
            result.success("删除成功!");
        }
        return result;
    }

    @Override
    public Result<CategoryResult> deleteBatch(String ids) {
        Result<CategoryResult> result = new Result<>();
        if (ids == null || "".equals(ids.trim())) {
            result.error500("参数不识别！");
        } else {
            this.categoryService.deleteSysCategory(ids);
            result.success("删除成功!");
        }
        return result;
    }

    /**
     * 通过id查询
     *
     * @param id
     * @return
     */
    @Override
    public Result<CategoryResult> queryById(String id) {
        Result<CategoryResult> result = new Result<>();
        Category sysCategory = categoryService.getById(id);
        if (sysCategory == null) {
            result.error500("未找到对应实体");
        } else {
            CategoryResult categoryResult = BeanUtil.toBean(sysCategory, CategoryResult.class);
//            categoryResult.setFillRuleId(Convert.toStr(categoryRuleService.fillRuleIdByCategoryId(sysCategory.getId())));
            result.setResult(categoryResult);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     * 通过Code查询
     *
     * @param
     * @return
     */
    @Override
    public Result<CategoryResult> queryByCode(String code) {
        Result<CategoryResult> result = new Result<>();
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Category::getCode, code);
        queryWrapper.in(Category::getTenantId, Arrays.asList(LoginUserContext.getInstance().getRelTenantId().split(",")));
        Category sysCategory = categoryService.getOne(queryWrapper, false);
        if (sysCategory == null) {
            result.error500("未找到对应实体");
        } else {
            CategoryResult categoryResult = BeanUtil.toBean(sysCategory, CategoryResult.class);
//            categoryResult.setFillRuleId(Convert.toStr(categoryRuleService.fillRuleIdByCategoryId(sysCategory.getId())));
            result.setResult(categoryResult);
            result.setSuccess(true);
        }
        return result;
    }

    /**
     * 加载单个数据 用于回显
     */
    @Override
    public Result<CategoryResult> getByFieldVal(String field, String val) {
        Result<CategoryResult> result = new Result<>();
        try {
            QueryWrapper<Category> query = new QueryWrapper<>();
            query.eq(field, val);
            List<Category> ls = this.categoryService.list(query);
            if (ls == null || ls.size() == 0) {
                result.setMessage("查询无果");
                result.setSuccess(false);
            } else if (ls.size() > 1) {
                result.setMessage("查询数据异常,[" + field + "]存在多个值:" + val);
                result.setSuccess(false);
            } else {
                result.setSuccess(true);
//                CategoryResult categoryResult = BeanUtil.toBean(ls.get(0), CategoryResult.class);
//                categoryResult.setFillRuleId(Convert.toStr(categoryRuleService.fillRuleIdByCategoryId(ls.get(0).getId())));
                result.setResult(BeanUtil.toBean(ls.get(0), CategoryResult.class));
            }
        } catch (Exception e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 加载节点的子数据
     */
    @Override

    public Result<List<TreeSelectResult>> listTreeChildren(Long pid) {
        Result<List<TreeSelectResult>> result = new Result<>();
        try {
            List<TreeSelectModel> ls = this.categoryService.queryListByPid(pid);
            result.setResult(BeanUtil.copyToList(ls, TreeSelectResult.class));
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 加载一级节点/如果是同步 则所有数据
     */
    @Override
    public Result<List<TreeSelectResult>> listTreeRoot(String pCode, Boolean async) {
        Result<List<TreeSelectResult>> result = new Result<>();
        try {
            List<TreeSelectModel> ls = this.categoryService.queryListByCode(pCode);
            if (!async) {
                loadAllCategoryChildren(ls);
            }
            result.setResult(BeanUtil.copyToList(ls, TreeSelectResult.class));
            result.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            result.setMessage(e.getMessage());
            result.setSuccess(false);
        }
        return result;
    }

    /**
     * 递归求子节点 同步加载用到
     */
    private void loadAllCategoryChildren(List<TreeSelectModel> ls) {
        for (TreeSelectModel tsm : ls) {
            List<TreeSelectModel> temp = this.categoryService.queryListByPid(tsm.getKey());
            if (temp != null && temp.size() > 0) {
                tsm.setChildren(temp);
                loadAllCategoryChildren(temp);
            }
        }
    }

    /**
     * 校验编码
     *
     * @param code
     * @return
     */
    @Override
    public Result<String> checkCode(@RequestParam(name = "name", required = false) String name, @RequestParam(name = "code", required = false) String code) {
        Result<String> result = new Result<>();
        //判断名称是否为空或者重复
        if (StrUtil.isBlank(name)) {
            return result.error500("分类名称不能为空");
        }
        if (StrUtil.isBlank(code)) {
            return result.error500("分类编码不能为空");
        }
        //判断名称\编码是否重复
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(Category::getTenantId, Arrays.asList(LoginUserContext.getInstance().getRelTenantId().split(",")));
        queryWrapper.eq(Category::getName, name).or().eq(Category::getCode, code);
        List<Category> list = this.categoryService.list(queryWrapper);
        if (CollectionUtil.isNotEmpty(list)) {
            Category category = list.get(0);
            if (name.equals(category.getName())) {
                result.error500("分类名称不能重复");
            } else {
                result.error500("分类编码不能重复");
            }
            return result;
        }
        result.setSuccess(true);
        return result;
    }


    /**
     * 分类字典树控件 加载节点
     *
     * @param pid
     * @param pcode
     * @param condition
     * @return
     */
    @Override

    public Result<List<TreeSelectResult>> loadDict(@RequestParam(name = "pid", required = false) Long pid, @RequestParam(name = "pcode", required = false) String pcode, @RequestParam(name = "condition", required = false) String condition) {
        Result<List<TreeSelectResult>> result = new Result<>();
        //pid如果传值了 就忽略pcode的作用
        if (Objects.isNull(pid)) {
            if (StrUtil.isEmpty(pcode)) {
                result.setSuccess(false);
                result.setMessage("加载分类字典树参数有误.[null]!");
                return result;
            } else {
                if (ICategoryService.ROOT_PID_VALUE.equals(pcode)) {
                    pid = ICategoryService.ROOT_PID_VALUE;
                } else {
                    pid = this.categoryService.queryIdByCode(pcode);
                }
                if (Objects.isNull(pid)) {
                    result.setSuccess(false);
                    result.setMessage("加载分类字典树参数有误.[code]!");
                    return result;
                }
            }
        }
        Map<String, String> query = null;
        if (StrUtil.isNotEmpty(condition)) {
            query = JSON.parseObject(condition, Map.class);
        }
        List<TreeSelectModel> ls = categoryService.queryListByPid(pid, query);
        result.setSuccess(true);
        result.setResult(BeanUtil.copyToList(ls, TreeSelectResult.class));
        return result;
    }

    /**
     * 分类字典控件数据回显[表单页面]
     *
     * @param ids
     * @return
     */
    @Override
    public Result<List<String>> loadDictItem(String ids) {
        Result<List<String>> result = new Result<>();
        // 非空判断
        if (StrUtil.isBlank(ids)) {
            result.setSuccess(false);
            result.setMessage("ids 不能为空");
            return result;
        }
        String[] idArray = ids.split(",");
        LambdaQueryWrapper<Category> query = new LambdaQueryWrapper<>();
        query.in(Category::getId, Arrays.asList(idArray));
        // 查询数据
        List<Category> list = this.categoryService.list(query);
        // 取出name并返回
        List<String> textList = list.stream().map(Category::getName).collect(Collectors.toList());
        result.setSuccess(true);
        result.setResult(textList);
        return result;
    }

    /**
     * [列表页面]加载分类字典数据 用于值的替换
     *
     * @param code
     * @return
     */
    @Override
    public Result<List<DictModel>> loadAllData(String code) {
        Result<List<DictModel>> result = new Result<>();
        LambdaQueryWrapper<Category> query = new LambdaQueryWrapper<>();
        if (StrUtil.isNotEmpty(code) && !"0".equals(code)) {
            query.likeRight(Category::getCode, code);
        }
        List<Category> list = this.categoryService.list(query);
        if (list == null || list.size() == 0) {
            result.setMessage("无数据,参数有误.[code]");
            result.setSuccess(false);
            return result;
        }
        List<DictModel> rdList = new ArrayList<>();
        for (Category c : list) {
            rdList.add(new DictModel(c.getId() + "", c.getName()));
        }
        result.setSuccess(true);
        result.setResult(rdList);
        return result;
    }

    /**
     * 根据父级id批量查询子节点
     *
     * @param parentIds
     * @return
     */
    @Override
    public Result<List<CategoryResult>> getChildListBatch(String parentIds) {
        try {
            QueryWrapper<Category> queryWrapper = new QueryWrapper<>();
            List<String> parentIdList = Arrays.asList(parentIds.split(","));
            queryWrapper.in("pid", parentIdList);
            List<Category> list = categoryService.list(queryWrapper);
            List<CategoryResult> resultList = new CategoryWrapper(list).wrapList();
//            setResultFillRuleIds(resultList);
            return Result.OK(resultList);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return Result.error("批量查询子节点失败：" + e.getMessage());
        }
    }

//    private void setResultFillRuleIds(List<CategoryResult> resultList) {
//        if (CollectionUtil.isNotEmpty(resultList)) {
//            List<Long> ids = resultList.stream().map(e -> Long.valueOf(e.getId())).collect(Collectors.toList());
//            Map<Long, CategoryRule> categoryRules = categoryRuleService.mapCategoryRule(ids);
//            for (CategoryResult result : resultList) {
//                CategoryRule categoryRule = categoryRules.get(Convert.toLong(result.getId()));
//                if (categoryRule != null) {
//                    result.setFillRuleId(Convert.toStr(categoryRule.getFillRuleId()));
//                    result.setCategoryRuleId(Convert.toStr(categoryRule.getId()));
//                }
//            }
//        }
//    }

    /**
     * 获取父级编码规则
     *
     * @param id
     * @return
     */
    public Result<CategoryResult> queryParentRuleById(String id) {
        Result<CategoryResult> result = new Result<>();
        try {
            List<CategoryResult> list = this.categoryService.queryParentRuleById(Convert.toLong(id));
            if (CollectionUtil.isNotEmpty(list)) {
                CategoryResult categoryResult = list.get(0);
//                FillRule fillRule = fillRuleService.getById(categoryResult.getFillRuleId());
//                if (fillRule != null) {
//                    categoryResult.setFillRuleName(fillRule.getRuleName());
//                }
//                result.setResult(fillRule == null ? null : categoryResult);
                result.setResult(categoryResult);
            }
            result.setSuccess(true);
        } catch (Exception e) {
            result.error500("获取数据失败");
        }
        return result;
    }

    /**
     * 启用/禁用
     *
     * @param id
     * @return
     */
    @Override
    public Result<List<String>> setEnableFlag(String id, Integer flag) {
        Result<List<String>> result = new Result<>();
        if (StrUtil.isBlank(id)) {
            return result.error500("分类ID不能为空");
        }
        if (ObjectUtil.isNull(flag)) {
            return result.error500("启用/禁用状态不能为空");
        }
        // 查找pid下的ID
        List<Long> idsList = this.categoryService.setEnableFlag(id, flag);
        if (CollectionUtil.isEmpty(idsList)) {
            return result.error500("无此数据");
        }
        result.setSuccess(true);
        result.setResult(idsList.stream().map(String::valueOf).collect(Collectors.toList()));
        return result;
    }

    /**
     * 通过ID获取所有的子分类信息
     *
     * @param id
     * @param isContainFlag 是否包含自己 { {1:包含 0:不包含}}
     * @return
     */
    @Override
    public Result<List<CategoryResult>> queryAllChildrenByPid(String id, Integer isContainFlag) {
        Result<List<CategoryResult>> result = new Result<>();
        List<Category> categoryList = this.categoryService.queryAllChildrenByPid(Convert.toLong(id), isContainFlag);
        List<CategoryResult> resultList = BeanUtil.copyToList(categoryList, CategoryResult.class);
//        setResultFillRuleIds(resultList);
        result.setSuccess(true);
        result.setResult(resultList);
        return result;
    }

}
